package com.Prot2;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Timer;
import java.util.TimerTask;

import com.Prot2.Logger.CoordinatorContinuous;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.text.format.Time;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;


public class BalanceUI extends Activity{
		
		private static final String TAG = "BalanceUI";		
		private Context 	c;
		
		private TextView	textCurrentlyDetectedLabel;
		private TextView 	textCurrentHome;
		private TextView 	textCurrentOffice;
		private TextView 	textCurrentIndoorOther;
		private TextView 	textCurrentOutdoor;
		private TextView 	textCurrentTransport;
		private TextView 	textCurrentOther;
		private TextView 	textAttainmentToday;
		private TextView 	textAttainmentWeek;
		private TextView	textDayPhrase;
	
		private ImageView	imgAttainmentToday;
		private ImageView	imgAttainmentWeek;
		
		private Button		buttonStartStopMyBalance;
		private Button		buttonMyBalancePreferences;
		
		private WakeLock	wakeLock;
		
		
		private static String[]	uiStats; //uiStats has [13], format: today: home,office,indoorOther,outdoor,transport,other,total day, total week
		
		private Handler uiUpdateHandler;		
		
		private void getViews(){
			getWindow().getAttributes().format = android.graphics.PixelFormat.RGBA_8888;
			
			setContentView(R.layout.balance);
			
			
			
			uiStats= new String[8];
			for(int i=0; i<uiStats.length ; i++){uiStats[i]="0";}
			
			buttonMyBalancePreferences = (Button) findViewById(R.id.button_MyBalance_Preferences);
			buttonStartStopMyBalance = (Button) findViewById(R.id.button_StartStop_MyBalance);
			
			textCurrentlyDetectedLabel = (TextView) findViewById(R.id.textCurrentlyDetectedContext);
			
			textCurrentHome = (TextView) findViewById(R.id.textCurrentHome);
			textCurrentOffice = (TextView) findViewById(R.id.textCurrentOffice);
			textCurrentIndoorOther = (TextView) findViewById(R.id.textCurrentIndoorOther);
			textCurrentOutdoor = (TextView) findViewById(R.id.textCurrentOutdoor);
			textCurrentTransport = (TextView) findViewById(R.id.textCurrentTransport);
			textCurrentOther = (TextView) findViewById(R.id.textCurrentOther);
			
			textAttainmentToday = (TextView) findViewById(R.id.textAttainmentToday);
			textAttainmentWeek = (TextView) findViewById(R.id.textAttainmentWeek);
			
			textDayPhrase = (TextView) findViewById(R.id.textDayPhrase);
			
			imgAttainmentToday = (ImageView) findViewById(R.id.imgAttainmentToday);
			
			if(Globals.balancingActive){
				buttonStartStopMyBalance.setText("Stop tracking");
			}else{
				buttonStartStopMyBalance.setText("Start tracking");
			}
			
			
			try {
				if(!initBalanceStats()){
					Toast.makeText(c, "Balance file old! Please renew!",Toast.LENGTH_LONG).show();
				}
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			buttonStartStopMyBalance.setOnClickListener(new OnClickListener(){
				@Override
				public void onClick(View v) {
					if(!Globals.balancingActive){

						v.getContext().startService(new Intent(v.getContext(),CoordinatorContinuous.class));
						wakeLock.acquire();
						Globals.balancingActive=true;
						Log.w(TAG,"MyBalance is now active");	

						
						uiUpdateHandler = new Handler();
						uiUpdateHandler.postDelayed(uiUpdateRunnable,0);						
						setTextsOnUi();
						
						buttonStartStopMyBalance.setText("Stop tracking");
					}else{
						v.getContext().stopService(new Intent(v.getContext(),CoordinatorContinuous.class));
						wakeLock.release();
						Globals.balancingActive=false;
						Log.w(TAG,"MyBalance is now turned off");
						buttonStartStopMyBalance.setText("Start tracking");
						uiUpdateHandler.removeCallbacks(uiUpdateRunnable);
					}
				}
		});
			
			buttonMyBalancePreferences.setOnClickListener(new OnClickListener(){
				@Override
				public void onClick(View v) {
				AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(c);
				alertDialogBuilder.setTitle("Information");
				alertDialogBuilder
					.setMessage("Your Goals are set to:\n"
								+"Home: \t"+(int)(Globals.balanceGoal[0]*100)+"% \n"
								+"Office: \t"+(int)(Globals.balanceGoal[1]*100)+"% \n"
								+"Indoor Other: \t"+(int)(Globals.balanceGoal[2]*100)+"% \n"
								+"Outdoor: \t"+(int)(Globals.balanceGoal[3]*100)+"% \n"
								+"Transport: \t"+(int)(Globals.balanceGoal[4]*100)+"% \n"
								+"Other: \t"+(int)(Globals.balanceGoal[5]*100)+"% \n"
								+"\n"
								+"Never turn off tracking (or phone) to get accurate results!")
					.setCancelable(true)
					.setNeutralButton("ok", new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							dialog.cancel();							
						}
					});
				AlertDialog alertDialog = alertDialogBuilder.create();
				alertDialog.show();
					
				}
			});
		}
		
		public void onCreate(Bundle savedInstanceState){
			super.onCreate(savedInstanceState);
			c=this;
			Globals.init();
			
			PowerManager pm = (PowerManager)c.getSystemService(Context.POWER_SERVICE);
			PowerManager.WakeLock w1 = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,TAG);
			wakeLock=w1;
			
			getViews();
			
		}
		
		@Override
		public void onStop(){
			super.onStop();
			if(Globals.balancingActive){
				uiUpdateHandler.removeCallbacks(uiUpdateRunnable);
			}
		}
		
		@Override
		public void onDestroy(){
			super.onStop();
			if(Globals.balancingActive){
				wakeLock.release();
				stopService(new Intent(getApplicationContext(),CoordinatorContinuous.class));
			}
		}
		
		@Override
		public void onRestart(){
			super.onRestart();
			getViews();
			uiUpdateHandler.postDelayed(uiUpdateRunnable, 0);
		}
		
		private void setTextsOnUi(){
			
			textCurrentlyDetectedLabel.setText("Last detected context: "+Globals.currentlyDetectedLabel);
			
			textCurrentHome.setText(""+uiStats[0]+"h");
			textCurrentOffice.setText(""+uiStats[1]+"h");
			textCurrentIndoorOther.setText(""+uiStats[2]+"h");
			textCurrentOutdoor.setText(""+uiStats[3]+"h");
			textCurrentTransport.setText(""+uiStats[4]+"h");
			textCurrentOther.setText(""+uiStats[5]+"h");			
			textAttainmentToday.setText(""+uiStats[6]+"/10");
			textAttainmentWeek.setText(""+uiStats[7]+"/10");
			
			if((Double.parseDouble(uiStats[6]))>4.5){
				if((Double.parseDouble(uiStats[6]))>7.5){
					imgAttainmentToday.setImageResource(R.drawable.smiley_happy);
				}else{
					imgAttainmentToday.setImageResource(R.drawable.smiley_neutral);
				}
			}else{
				imgAttainmentToday.setImageResource(R.drawable.smiley_sad);
			}
			
			if(Double.parseDouble(uiStats[6])>7.5){
				if(Double.parseDouble(uiStats[3])<1){
					textDayPhrase.setText("Don\'t forget to get some air too!");
				}else{
					textDayPhrase.setText("You\'re doing great, keep on going!");
				}
			}else{
				if(Double.parseDouble(uiStats[1])<4){
					textDayPhrase.setText("Come on, let\'s get to work!");
				}else{
					if(Double.parseDouble(uiStats[0])<1){
						textDayPhrase.setText("Make sure you get some rest as well :)");
					}
				}
			}
			
			
			
			Log.w(TAG,"updating the UI now");
			uiUpdateHandler.postDelayed(uiUpdateRunnable, Globals.balancingUiUpdateRate);
		}
		
		
		private Runnable uiUpdateRunnable = new Runnable(){
			@Override
			public void run(){
				
				
				try {
					if(!updateBalanceStats()){
						Toast.makeText(c, "Balance file old! Please renew!",Toast.LENGTH_SHORT).show();
					}
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				setTextsOnUi();
				
			}
		};
		
		
		private static boolean updateBalanceStats() throws FileNotFoundException{
			
			FileInputStream fis = new FileInputStream(Globals.balanceFilePath);
			BufferedReader br = new BufferedReader(new InputStreamReader(fis));
			
			Time date = new Time();
			Time dateStart = new Time();
			int label;
			int[] labelCount = new int[6];
			
		    try {
		        String line;
		        
		        if((line = br.readLine()) != null){  //read first line to determine first date
					String[] RowData = line.split(",");
					dateStart.parse3339(RowData[0]);
					label = Integer.parseInt(RowData[1]);
					
					if(Globals.now.monthDay-dateStart.monthDay>6){
						System.out.println("old balance file deteced");
						fis.close();
						return false;
					}
					
		        }

		        int[] tempLabelCount = new int[6];
		        
		        long time1 = dateStart.toMillis(false);
		        long time2 = 0;
		        
		        while ((line = br.readLine()) != null) {
					String[] RowData = line.split(",");
					date.parse3339(RowData[0]);
					Globals.now.switchTimezone("UTC");
					if(date.monthDay!=Globals.now.monthDay){
						//Ignore all this data
					}else{

						label = Integer.parseInt(RowData[1]);
						switch(label){
						case 0: tempLabelCount[0]++; break;
						case 1: tempLabelCount[1]++; break;
						case 2: tempLabelCount[3]++; break;
						case 3: tempLabelCount[2]++; break;
						case 4: tempLabelCount[2]++; break;
						case 5: tempLabelCount[2]++; break;
						case 6: tempLabelCount[3]++; break;
						case 7: tempLabelCount[3]++; break;
						case 8: tempLabelCount[3]++; break;
						case 9: tempLabelCount[4]++; break;
						case 10: tempLabelCount[4]++; break;
						case 11: tempLabelCount[4]++; break;
						case 12: tempLabelCount[4]++; break;
						case 13: tempLabelCount[4]++; break;
						case 14: tempLabelCount[5]++; break;
						default: break;
						}
						
						time2 = date.toMillis(false);
						if((time2-time1)>=Globals.balanceContextMajorityTime){
							int resultingLabel=0;
							for(int i=1; i<tempLabelCount.length; i++){
								if(tempLabelCount[i]>tempLabelCount[resultingLabel]){
									resultingLabel=i;
								}
							}
							labelCount[resultingLabel]++;
							time1=time2;
						}
					}
		        }
		    }
		    catch (IOException ex) {
		        // handle exception
		    }
		    finally {
		        try {
		            fis.close();
		        }
		        catch (IOException e) {
		            // handle exception
		        }
		    }
		    
		    double[] statsThisDay = new double[6];
		    double dayScore = 0;
		    
				int total = 0;
				for(int i:labelCount){
					total+=i; //overall total labels counted during each day
					//System.out.println("day, count, total: "+day+" , "+i+" , "+total);
					} 
				double  tempDayScore = 0;
				for(int i=0; i<labelCount.length ; i++){
					statsThisDay[i]=((double)labelCount[i])/((double)total);
					//System.out.println("stat portion: day: "+day+" label: "+i+" score: "+statsByDay[day][i]);
					tempDayScore+=Math.abs(Globals.balanceGoal[i]-statsThisDay[i])/labelCount.length;
				}
				dayScore = 1-tempDayScore;
				if(Double.isNaN(dayScore)){
					dayScore = 0;
				}
			
			for(int i=0; i<statsThisDay.length; i++){
				//Assign current percentages by label (for this day)
				//uiStats[i]=String.format("%.2f", statsThisDay[i]*100);
				//Assign current hours by label for this day
				uiStats[i]=String.format("%.2f", ((double)labelCount[i])/((double)6));
			}
			
			//Assign Day Score
			uiStats[6] = String.format("%.1f", dayScore*10);
		 return true;   
		}
		
		
		
		private static boolean initBalanceStats() throws FileNotFoundException{
			
			FileInputStream fis = new FileInputStream(Globals.balanceFilePath);
			BufferedReader br = new BufferedReader(new InputStreamReader(fis));
			
			Time date = new Time();
			Time dateStart = new Time();
			int label;
			int[][] labelCount = new int[7][4];
			
		    try {
		        String line;
		        
		        if((line = br.readLine()) != null){  //read first line to determine first date
					String[] RowData = line.split(",");
					dateStart.parse3339(RowData[0]);
					label = Integer.parseInt(RowData[1]);
					
					if(Globals.now.monthDay-dateStart.monthDay>6){
						System.out.println("old balance file deteced");
						fis.close();
						return false;
					}
					
		        }
		        
		        int[][] tempLabelCount = new int[7][6];
		        
		        while ((line = br.readLine()) != null) {
					String[] RowData = line.split(",");
					date.parse3339(RowData[0]);
					label = Integer.parseInt(RowData[1]);				
	
			        	long time1 = dateStart.toMillis(false);
			        	long time2 = 0;					
					
						Globals.now.switchTimezone("UTC");
						int day = date.monthDay-dateStart.monthDay;
						//System.out.println("day: "+day);
						if(day<7){
							switch(label){
							case 0: tempLabelCount[day][0]++; break;
							case 1: tempLabelCount[day][1]++; break;
							case 2: tempLabelCount[day][3]++; break;
							case 3: tempLabelCount[day][2]++; break;
							case 4: tempLabelCount[day][2]++; break;
							case 5: tempLabelCount[day][2]++; break;
							case 6: tempLabelCount[day][3]++; break;
							case 7: tempLabelCount[day][3]++; break;
							case 8: tempLabelCount[day][3]++; break;
							case 9: tempLabelCount[day][4]++; break;
							case 10: tempLabelCount[day][4]++; break;
							case 11: tempLabelCount[day][4]++; break;
							case 12: tempLabelCount[day][4]++; break; 
							case 13: tempLabelCount[day][4]++; break;
							case 14: tempLabelCount[day][5]++; break; //Null class
							default: break;
							}
						}
						
						time2 = date.toMillis(false);
						if((time2-time1)>=Globals.balanceContextMajorityTime){
							int resultingLabel=0;
							for(int i=1; i<tempLabelCount[0].length; i++){
								if(tempLabelCount[day][i]>tempLabelCount[day][resultingLabel]){
									resultingLabel=i;
								}
							}
							labelCount[day][resultingLabel]++;
							time1=time2;
						}
		        }
		    }
		    catch (IOException ex) {
		        // handle exception
		    }
		    finally {
		        try {
		            fis.close();
		        }
		        catch (IOException e) {
		            // handle exception
		        }
		    }

		    double[][] statsByDay = new double[7][6];
		    double[] dayScore = new double[7];
		    
			for(int day=0; day<7; day++){ //iteration through weekdays
				int total = 0;
				for(int i:labelCount[day]){
					total+=i; //overall total labels counted during each day
					//System.out.println("day, count, total: "+day+" , "+i+" , "+total);
					} 
				double  tempDayScore = 0;
				for(int i=0; i<labelCount[day].length ; i++){ //computes overall day score, comparing achieved percentage with goal percentage
					statsByDay[day][i]=((double)labelCount[day][i])/((double)total);
					//System.out.println("stat portion: day: "+day+" label: "+i+" score: "+statsByDay[day][i]);
					tempDayScore+=Math.abs(Globals.balanceGoal[i]-statsByDay[day][i]);
				}
				dayScore[day] = 1-tempDayScore;
				if(Double.isNaN(dayScore[day])){
					dayScore[day]=0;
				}
			}
		
			
			double tempWeekScore=0;
			for(double a:dayScore){
				tempWeekScore+=a;
			}
			//Assign Week Score
			uiStats[7]=String.format("%.1f", tempWeekScore/((double)(Globals.now.monthDay-dateStart.monthDay+1))*10);
		    
		 return true;   
		}
		
		
}
	
		
		


